package com.acme.bankapp.account.impl;

import com.acme.bankapp.account.AbstractAccount;
import com.acme.bankapp.account.AccountClosedException;
import com.acme.bankapp.account.AccountType;
import com.acme.bankapp.account.NotEnoughFundsException;
import com.acme.bankapp.account.OverDraftLimitExceededException;
import com.acme.bankapp.domain.bank.Account;


/**
 * @author Andrey Alekov
 * Saving account implementation
 */
public class SavingAccount extends AbstractAccount{
	
	/**
	 * Constructor.
	 * @param amount the initial value.
	 * @throws IllegalArgumentException when amount is negative
	 * @deprecated Cause it's not persistent by business logic. Use just for study.
	 */
	public SavingAccount(final double amount) throws IllegalArgumentException {
		super(amount);
	}
	/*
	 * (non-Javadoc)
	 * @see com.acme.bankapp.account.AbstractAccount#AbstractAccount(double, long, AccountType)
	 */
	public SavingAccount(double amount, long accountId) {
		super(amount, accountId, AccountType.SAVING);
	}

	/*
	 * (non-Javadoc)
	 * @see com.acme.bankapp.account.AbstractAccount#deposit(double)
	 */
	@Override
	public void deposit(double amount) throws AccountClosedException {
		if (!isOpened()){
			throw new AccountClosedException("Account closed.");
		}
		balance += amount;
	}

	/*
	 * (non-Javadoc)
	 * @see com.acme.bankapp.account.AbstractAccount#withdraw(double)
	 */
	@Override
	public void withdraw(double amount) throws OverDraftLimitExceededException, 
	NotEnoughFundsException, AccountClosedException {
		if (!isOpened()){
			throw new AccountClosedException("Account closed.");
		}
		if (balance < Math.abs(amount)){
			throw new NotEnoughFundsException("Account limit exceeded. "
					+ "Avaliabale balance " + this.balance);
		}
		balance -= amount;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.acme.bankapp.account.AbstractAccount#maximumAmountToWithdraw()
	 */
	@Override
	public double maximumAmountToWithdraw() {
		return balance;
	}

	/*
	 * (non-Javadoc)
	 * @see com.acme.bankapp.account.AbstractAccount#setAccountType(com.acme.bankapp.account.AccountType)
	 */
	@Override
	public void setAccountType(AccountType type) throws UnsupportedOperationException{
		if (type == AccountType.CHECKING){
			throw new UnsupportedOperationException("Unsupported account type");
		}
		this.accountType = type;
	}

	
	/*
	 * (non-Javadoc)
	 * @see com.acme.bankapp.domain.bank.Account#getOverdraftAccount()
	 */
	@Override
	public Account getOverdraftAccount() throws UnsupportedOperationException {
		throw new UnsupportedOperationException("This account don't support "
				+ "overdraft.");
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.acme.bankapp.domain.bank.Account#hasOverdraft()
	 */
	@Override
	public boolean hasOverdraft() {
		return false;
	}
}
